﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.Net.DesignByContract;

namespace Common.Net.DataStructures
{
    public abstract class SingleRun<TRet>
    {
        readonly object _runSyncObj = new object();
        bool _alreadyRun;

        public bool AlreadyRun
        {
            get { return _alreadyRun; }
        }

        public TRet Run()
        {
            lock (_runSyncObj)
            {
                Require.IsFalse(() => AlreadyRun);
                _alreadyRun = true;
            }

            return RunInternal();
        }

        /// <summary>
        /// Guaranteed to be called only once
        /// </summary>
        protected abstract TRet RunInternal();
    }
}
